package com.webapp.helper;

import com.webapp.view.BaseContants;
import okhttp3.HttpUrl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import java.io.ByteArrayInputStream;
import java.security.PrivateKey;
import java.security.Signature;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;

public class WechatUtil {

private static final Logger LOGGER = LoggerFactory.getLogger(WechatUtil.class);
	
	
	/**
	 * 获取accessToken
	 * @param appId
	 * @param appSecret
	 * @return
	 */
	public static String getAccessToken(String appId, String appSecret) {
		String access = null;
		try {
			String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+appId+"&secret="+appSecret;
			String result = HttpUtils.get(url);
			JSONObject jsonObject = JSON.parseObject(result);
			LOGGER.warn("[WechatUtil.getAccessToken:{},==={},==={}]",appId,appSecret,result);
			access = jsonObject.getString("access_token");
		} catch (Exception e) {
			LOGGER.error("e:get access token:{}",e);
		}
		return access;
	}

	public static String getOpenId(String appid,String secret,String code) {
		String openid = null;
		try {
			String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid="+appid+"&secret="+secret+"&code="+code+"&grant_type=authorization_code";
			String result = HttpUtils.get(url);
			JSONObject jsonObject = JSON.parseObject(result);
			LOGGER.warn("[WechatUtil.getOpenid:{},==={},==={},==={}]",result,appid,secret,code);
			openid = jsonObject.getString("openid");
		} catch (Exception e) {
			LOGGER.error("e get o0c7k1G6GaBQ9ZwImjWx3PiiFAU0 openid:{}",e);
		}
		return openid;
	}

	public static JSONObject getPrepayId(String jsonString,String scheme,String sign) {
		try {
			String url = "https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi";
			String result = HttpUtils.postWxJson(url, jsonString,scheme+" "+sign);
			JSONObject jsonObject = JSON.parseObject(result);
			LOGGER.warn("[WechatUtil.getpayinfo:{},==={}]",result,jsonString);
			return jsonObject;
		} catch (Exception e) {
			LOGGER.error("e getPrepayId  :{}",e);
		}
		return null;
	}


	public static Map<String,Object> getWechatOrderId(String total, String openid, String desc, String appId, String mchid, String key,String noticeUrl,String seriaNo) {
		try {
			String schema = "WECHATPAY2-SHA256-RSA2048";
			PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(new ByteArrayInputStream(key.getBytes("utf-8")));
			String nonceStr = StringUtil.getRandomString(28);
			long timestamp = System.currentTimeMillis();
			String orderNo = StringUtil.getRandomString(8)+"_"+timestamp;
			Map<String, Object> map = new HashMap<String, Object>();
			Map<String, Object> returnMap = new HashMap<String, Object>();
			Map<String, Object> amount = new HashMap<String, Object>();
			Map<String, Object> payer = new HashMap<String, Object>();
			amount.put("total", Integer.valueOf(total));
			amount.put("currency", "CNY");
			payer.put("openid", openid);
			map.put("amount", amount);
			map.put("payer", payer);
			map.put("mchid", mchid);
			map.put("out_trade_no", orderNo);
			map.put("appid", appId);
			map.put("description", desc);
			map.put("notify_url", noticeUrl);
			HttpUrl httpurl = HttpUrl.parse("https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi");
			String message = buildMessage("POST", httpurl, timestamp/1000, nonceStr, JSONObject.toJSONString(map));
			String signatureStr = sign(message.getBytes("utf-8"),merchantPrivateKey);
			String signStr = "mchid=\"" + mchid + "\","
					+ "nonce_str=\"" + nonceStr + "\","
					+ "timestamp=\"" + timestamp/1000 + "\","
					+ "serial_no=\"" + seriaNo + "\","
					+ "signature=\"" + signatureStr + "\"";
			JSONObject obj =  getPrepayId(JSONObject.toJSONString(map),schema,signStr);
			String prepay_id = obj.getString("prepay_id");
			returnMap.put("prepay_id", prepay_id);
			returnMap.put("appId",appId);
			returnMap.put("timeStamp", String.valueOf(timestamp/1000));
			returnMap.put("nonceStr", nonceStr);
			returnMap.put("package", "prepay_id="+prepay_id);
			returnMap.put("signType", "RSA");
			String needSignStr = appId+"\n"+timestamp/1000+"\n"+nonceStr+"\n"+"prepay_id="+prepay_id+"\n";
			returnMap.put("orderNo", orderNo);
			Signature sign = Signature.getInstance("SHA256withRSA");
			sign.initSign(merchantPrivateKey);
			sign.update(needSignStr.getBytes("utf-8"));
			String signature = Base64.getEncoder().encodeToString(sign.sign());
			returnMap.put("paySign", signature);
			return returnMap;
		} catch (Exception e) {
			LOGGER.error("e:{}",e);
		}
		return null;
	}

	static String sign(byte[] message,PrivateKey key) {
		try {
			Signature sign = Signature.getInstance("SHA256withRSA");
			sign.initSign(key);
			sign.update(message);
			return Base64.getEncoder().encodeToString(sign.sign());
		}catch (Exception e){
			e.printStackTrace();
		}
		return null;
	}

	static String buildMessage(String method, HttpUrl url, long timestamp, String nonceStr, String body) {
		String canonicalUrl = url.encodedPath();
		if (url.encodedQuery() != null) {
			canonicalUrl += "?" + url.encodedQuery();
		}
		return method + "\n"
				+ canonicalUrl + "\n"
				+ timestamp + "\n"
				+ nonceStr + "\n"
				+ body + "\n";
	}




}
